﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

namespace SpectrumAnalyser.ServiceClientProxy
{
    public class CustomDebugServiceClientGenerator : ServiceClientGenerator
    {
        public CustomDebugServiceClientGenerator(Type serviceContractType)
            : base(serviceContractType)
        {
        }

        protected override void AddConstructor()
        {
            var constructorArgs = new[]
                                      {
                                          typeof (IEnumerable<IEndpointBehavior>),
                                          typeof (Binding), 
                                          typeof (EndpointAddress)
                                      };
            var constructorBuilder = this._serviceClientTypeBuilder.DefineConstructor(MethodAttributes.Public,
                                                                                      CallingConventions.Standard,
                                                                                      constructorArgs);
            constructorBuilder.DefineParameter(1, ParameterAttributes.None, "endpointBehaviors");
            constructorBuilder.DefineParameter(2, ParameterAttributes.None, "binding");
            constructorBuilder.DefineParameter(3, ParameterAttributes.None, "endpoint");
            // Generate IL for constructor that calls base class constructor
            ILGenerator contstructorIL = constructorBuilder.GetILGenerator();
            contstructorIL.Emit(OpCodes.Ldarg_0);
            contstructorIL.Emit(OpCodes.Ldarg_1);
            contstructorIL.Emit(OpCodes.Ldarg_2);
            contstructorIL.Emit(OpCodes.Ldarg_3);
            contstructorIL.Emit(OpCodes.Call,
                                this._baseServiceClientType.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null,
                                                                           constructorArgs, null));
            contstructorIL.Emit(OpCodes.Ret);
        }

        protected override Type GetBaseTypeGenericDefenition()
        {
            return typeof(CustomClientBase<>);
        }
    }
}